package org.qianji.goosql.cond;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.qianji.goosql.dql.QueryStatement;
import org.qianji.goosql.exception.ConditionException;
import org.qianji.goosql.field.Field;

/**
 * IN子查询范围查询条件。
 * 
 * @author gmz
 * 
 */
public class InSubQuery extends In {

	/**
	 * 
	 */
	private static final long serialVersionUID = -7016602568339670771L;

	private QueryStatement subQuery;

	/**
	 * 构造IN子查询范围查询条件。
	 * 
	 * @param field
	 *            {@link Field} 查询字段
	 * @param subQuery
	 *            {@link QueryStatement} 子查询语句
	 */
	public InSubQuery(Field field, QueryStatement subQuery) {
		super();
		if (field == null || subQuery == null) {
			throw new NullPointerException("args can't be null");
		}
		int size = subQuery.getSelect().size();
		if (size != 1) {
			throw new ConditionException("the size of subQuery must be 1");
		}
		this.field = field;
		this.subQuery = subQuery;
	}

	/**
	 * 获取子查询语句
	 * 
	 * @return {@link QueryStatement} 子查询语句
	 */
	public QueryStatement getSubQuery() {
		return subQuery;
	}

	@Override
	public String toSql() {
		StringBuffer cond = new StringBuffer(field.toSql()).append(" IN(").append(subQuery.toSql()).append(")");
		return cond.toString();
	}

	@Override
	public List<Object> getPlacedParameters() {
		List<Object> ppl = new ArrayList<Object>();
		ppl.addAll(field.getPlacedParameters());
		ppl.addAll(subQuery.getPlacedParameters());
		return ppl;
	}

	@Override
	public Map<String, Object> getNamedParameters() {
		Map<String, Object> npm = new HashMap<String, Object>();
		npm.putAll(field.getNamedParameters());
		npm.putAll(subQuery.getNamedParameters());
		return npm;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null || !(obj instanceof InSubQuery)) {
			return false;
		}
		InSubQuery other = (InSubQuery) obj;
		if (field.equals(other.getField()) && subQuery.equals(other.getSubQuery())) {
			return true;
		}
		return false;
	}

	@Override
	public int hashCode() {
		int hc = 37 * 17 + field.hashCode();
		hc = 37 * hc + subQuery.hashCode();
		return hc;
	}

	@Override
	public String toString() {
		return toSql();
	}

}
